package com.hand.wfive.activity.sign

import android.annotation.SuppressLint
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.pdf.PdfRenderer
import android.os.ParcelFileDescriptor
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.isVisible
import com.doris.media.picker.model.MediaPickerParameter
import com.doris.media.picker.result.contract.MediaPickerContract
import com.qmuiteam.qmui.arch.SwipeBackLayout
import com.hand.wfive.App
import com.hand.wfive.R
import com.hand.wfive.adapter.FragmentAdapter
import com.hand.wfive.base.BaseFragment
import com.hand.wfive.entity.FileEvent
import com.hand.wfive.entity.FileModel
import com.hand.wfive.entity.ImageVo
import com.hand.wfive.entity.Params
import com.hand.wfive.entity.SignLibEvent
import com.hand.wfive.fragment.sign.SignItemFragment
import com.hand.wfive.util.FuncSwitchUtils
import com.hand.wfive.util.ImageUtils
import com.hand.wfive.util.bottomShow
import com.hand.wfive.util.click.singleClick
import com.hand.wfive.util.oss.OssCallBack
import com.hand.wfive.util.oss.OssRequest
import com.hand.wfive.util.pageChange
import com.hand.wfive.view.InputDialog
import com.hand.wfive.dialog.MsgDialog
import com.hand.wfive.view.SignLibrarayDialog
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_sign.*
import org.greenrobot.eventbus.EventBus
import org.jetbrains.anko.contentView
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.toast
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList

@SuppressLint("SetTextI18n")
class SignActivity : BaseSignActivity(), SignItemFragment.Listener {

    companion object {
        fun show(context: Context, model: FileModel) {
            context.startActivity<SignActivity>(Params.model to model)
        }
    }

    private var mFileStatus = Params.fileStatusUnsign

    private val mFragments = ArrayList<BaseFragment>()
    private lateinit var mSignFragment: SignItemFragment

    private var mPreview = false
    private val mSdf = SimpleDateFormat("示例：yyyy年M月dd日", Locale.CHINA)

    private var mSignType = ""
    private lateinit var mTurnSign: ActivityResultLauncher<Intent>
    private lateinit var mTurnPreview: ActivityResultLauncher<Intent>
    private lateinit var mPickerImage: ActivityResultLauncher<MediaPickerParameter>

    override fun getContentViewId() = R.layout.activity_sign

    @SuppressLint("CheckResult")
    override fun init() {
        super.init()
        mFileStatus = mFileModel.status

        mTurnSign = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (it.resultCode == RESULT_OK) {
                val path = it.data?.getStringExtra(Params.path)
                if (!path.isNullOrEmpty()) {
                    mSignFragment.addImage(path, true)
                    mFileModel.status = Params.fileStatusSign
                    FuncSwitchUtils.addUseCount(FuncSwitchUtils.FuncSignAdd)

                    val flag = it.data?.getIntExtra(Params.flag, -1)
                    val type = it.data?.getStringExtra(Params.type)
                    if (flag == 2 && type in arrayOf(Params.fileTypeSign, Params.fileTypeStamp)) {
                        EventBus.getDefault().post(SignLibEvent(type))
                    }
                }
            }
        }
        mTurnPreview = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (it.resultCode == RESULT_OK) finish()
        }
        mPickerImage = registerForActivityResult(MediaPickerContract()) {
            if (it.isPicker) {
                mSignFragment.addImage(it.getFirstPath())
                mFileModel.status = Params.fileStatusSign
                FuncSwitchUtils.addUseCount(FuncSwitchUtils.FuncAlbum)
            }
        }

        if (contentView is SwipeBackLayout) {
            (contentView as SwipeBackLayout).isEnableSwipeBack = false
        }

        initTopBar(topBar)

        tv_tip.isSelected = true
        tv_title.text = mFileModel.fileName
        qib_rename.singleClick { rename() }

        qib_pre.singleClick {
            val item = qvp_sign.currentItem - 1
            if (item in 0 until mFragments.size) {
                qvp_sign.setCurrentItem(item, false)
                qib_next.isEnabled = true
                qib_pre.isEnabled = (item - 1) in 0 until mFragments.size
            } else {
                qib_pre.isEnabled = false
            }
        }
        qib_next.singleClick {
            val item = qvp_sign.currentItem + 1
            if (item in 0 until mFragments.size) {
                qvp_sign.setCurrentItem(item, false)
                qib_pre.isEnabled = true
                qib_next.isEnabled = (item + 1) in 0 until mFragments.size
            } else {
                qib_next.isEnabled = false
            }
        }

        qib_sign.singleClick { showSignDialog() }
        qib_stamp.singleClick { showStampDialog() }
        qib_date.singleClick { showDateDialog() }
        qib_preview.singleClick {
            mPreview = true
            onSave()
        }

    }

    @SuppressLint("CheckResult")
    override fun onInitData() {
        showLoadingTipC()
        Observable.create<Int> {
            loadFragments()
            it.onNext(RESULT_OK)
            it.onComplete()
        }.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe {
            dismissTip()
            initSign()
        }
    }

    private fun initSign() {
        qvp_sign.adapter = FragmentAdapter(supportFragmentManager, mFragments)
        qvp_sign.setSwipeable(false)

        qvp_sign.pageChange {
            tv_index.text = "${it + 1}/${mFragments.size}"
            mSignFragment = mFragments[it] as SignItemFragment
        }

        tv_index.isVisible = true
        tv_index.text = "1/${mFragments.size}"
        mSignFragment = mFragments[0] as SignItemFragment

        if (mFragments.size > 1) {
            qib_pre.isVisible = true
            qib_pre.isEnabled = false

            qib_next.isVisible = true
            qib_next.isEnabled = mFragments.size > 1
        }
    }

    private fun loadFragments() {
        when (mFileModel.type) {
            Params.fileTypeImage, Params.fileTypeScan -> {
                if (mFileModel.fileId.contains(",")) {
                    mFileModel.fileId.split(",").forEach {
                        mFragments.add(
                            SignItemFragment.load(OssRequest.getInstance().getFileUrl(it), this)
                        )
                    }
                } else {
                    mFragments.add(
                        SignItemFragment.load(
                            OssRequest.getInstance().getFileUrl(mFileModel.fileId), this
                        )
                    )
                }
            }

            Params.fileTypePdf -> {
                val imgList = ArrayList<String>()
                val parcelFileDescriptor = ParcelFileDescriptor.open(
                    File(mFileModel.filePath), ParcelFileDescriptor.MODE_READ_ONLY
                )
                if (parcelFileDescriptor != null) {
                    val pdfRenderer = PdfRenderer(parcelFileDescriptor)
                    val pageCount = pdfRenderer.pageCount
                    for (i in 0 until pageCount) {
                        val page = pdfRenderer.openPage(i)
                        val width = resources.displayMetrics.densityDpi / 72 * page.width
                        val height = resources.displayMetrics.densityDpi / 72 * page.height
                        val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
                        val canvas = Canvas(bitmap)
                        canvas.drawColor(Color.WHITE)
                        canvas.drawBitmap(bitmap, 0f, 0f, null)
                        page.render(
                            bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY
                        )
                        imgList.add(
                            ImageUtils.saveBitmapJPG(
                                mContext, bitmap, App.getContext().cacheTempPath
                            )
                        )
                        mPdfPageSize.add(Pair(page.width, page.height))
                        page.close()
                    }
                    parcelFileDescriptor.close()
                    pdfRenderer.close()
                }
                imgList.forEach {
                    mFragments.add(SignItemFragment.load(it, this))
                }
            }

            Params.fileTypeWord -> {
                imageVoList.forEach { imageVo ->

                    mFragments.add(
                        SignItemFragment.load(
                            imageVo.url,
                            this
                        )
                    )
                }
            }
        }
    }

    /**保存**/
    private var mSaveIndex = 0

    override fun onSave() {
        //此处开始保存，通过loadSaveData轮询获取的结果
        showLoadingTipC()
        mUpdate = false
        mSaveIndex = 0
        mSaveData.clear()
        (mFragments[mSaveIndex] as SignItemFragment).loadSaveData()
    }

    override fun onItemSave(data: Pair<Boolean, String>) {
        if (data.first) mUpdate = true
        mSaveData.add(data)
        mSaveIndex++
        if (mSaveIndex < mFragments.size) {
            (mFragments[mSaveIndex] as SignItemFragment).loadSaveData()
        } else {
            if (mPreview) {
                dismissTip()
                mTurnPreview.launch(
                    SignPreviewActivity.showIntent(
                        mContext, mFileModel, mSaveData, mPdfPageSize, mUpdate
                    )
                )
                mPreview = false
            } else if (mUpdate) {
                if (mFileModel.type == Params.fileTypeWord) {
                    if (imageVoList.isEmpty()) {
                        showNormalTip("数据错误，请联系客服")
                    } else {
                        var list = ArrayList<ImageVo>()
                        for (i in imageVoList.indices) {
                            if (mSaveData[i].first) {
                                val vo = imageVoList[i]
                                var imageVo = ImageVo(vo.pageIdx, vo.size, vo.slideId, vo.url)
                                imageVo.path = mSaveData[i].second

                                list.add(imageVo)
                            }

                        }
                        saveWord(list, imageVoList)
                    }

                } else {
                    save()
                }


            } else {
                showNormalTip("未修改，无需保存")
            }
        }
    }

    /**重命名**/
    private fun rename() {
        InputDialog(
            mContext, "重命名", mFileModel.fileName, content = mFileModel.fileName
        ) { dialog, value ->
            if (value.isEmpty()) {
                toast("请输入文件名！")
                return@InputDialog
            }
            if (value == mFileModel.fileName) {
                dialog.dismiss()
                return@InputDialog
            }
            dialog.dismiss()
            showLoadingTipC()
            OssRequest.getInstance().renameFile(mFileModel, value, object : OssCallBack {
                override fun onSuccess() {
                    dismissTip()
                    mFileModel.fileName = value
                    tv_title.text = mFileModel.fileName
                    EventBus.getDefault().post(FileEvent(Params.fileTypeAll, mFileModel.status))
                }

                override fun onFailure(msg: String) {
                    showNormalTip(msg)
                }
            })
        }.show()
    }

    /**签字**/
    private fun showSignDialog() {
        val dialog = Dialog(mContext, R.style.CustomDialog)
        dialog.setContentView(R.layout.dialog_sign)
        dialog.find<TextView>(R.id.tv_title).text = mFileModel.fileName
        dialog.find<ImageView>(R.id.iv_library).singleClick {
            dialog.dismiss()
            SignLibrarayDialog(mContext, Params.fileTypeSign) {
                mSignType = Params.fileTypeSign
                if (it == "needVip") {
                    showVip()
                } else if (it.isEmpty()) {
                    adCloseCallBack()
                } else {
                    mSignFragment.addImage(it, true)
                    mFileModel.status = Params.fileStatusSign
                }
            }.show()
        }
        dialog.find<ImageView>(R.id.iv_write).singleClick {
            dialog.dismiss()
            if (FuncSwitchUtils.canUse(FuncSwitchUtils.FuncSignAdd)) {
                mTurnSign.launch(SignatureWriteActivity.showIntent(mContext))
            } else {
                showVip()
            }
        }
        dialog.find<ImageView>(R.id.iv_cancel).singleClick {
            dialog.dismiss()
            if (mFileStatus == Params.fileStatusUnsign) {
                mFileModel.status = Params.fileStatusUnsign
            } else {
                mFileModel.status = Params.fileStatusSign
            }
            mSignFragment.clearSign()
        }
        dialog.bottomShow()
    }

    /**签章**/
    private fun showStampDialog() {
        val dialog = Dialog(mContext, R.style.CustomDialog)
        dialog.setContentView(R.layout.dialog_sign_stamp)
        dialog.find<TextView>(R.id.tv_library).singleClick {
            dialog.dismiss()
            SignLibrarayDialog(mContext, Params.fileTypeStamp) {
                mSignType = Params.fileTypeStamp
                if (it == "needVip") {
                    showVip()
                } else if (it.isEmpty()) {
                    adCloseCallBack()
                } else {
                    mSignFragment.addImage(it, true)
                    mFileModel.status = Params.fileStatusSign
                }
            }.show()
        }
        dialog.find<TextView>(R.id.tv_album).singleClick {
            dialog.dismiss()
            if (FuncSwitchUtils.canUse(FuncSwitchUtils.FuncAlbum)) {
                mPickerImage.launch(MediaPickerParameter())
            } else {
                showVip()
            }
        }
        dialog.bottomShow()
    }

    override fun adCloseCallBack() {
        super.adCloseCallBack()
        mBaseHandler.post {
            if (mSignType == Params.fileTypeSign) {
                mTurnSign.launch(SignatureWriteActivity.showIntent(mContext, 2))
            } else if (mSignType == Params.fileTypeStamp) {
                mTurnSign.launch(Intent(mContext, MakeStampActivity::class.java))
            }
            mSignType = ""
        }
    }

    /**日期**/
    private fun showDateDialog() {
        val dialog = Dialog(mContext, R.style.CustomDialog)
        dialog.setContentView(R.layout.dialog_sign_date)

        val today = Calendar.getInstance().time
        mSdf.applyPattern("示例：yyyy年M月dd日")
        dialog.find<TextView>(R.id.tv_date_ymd).text = mSdf.format(today)
        mSdf.applyPattern("示例：yyyyMMdd")
        dialog.find<TextView>(R.id.tv_date_num).text = mSdf.format(today)
        mSdf.applyPattern("示例：yyyy/MM/dd")
        dialog.find<TextView>(R.id.tv_date_ymd_s).text = mSdf.format(today)
        mSdf.applyPattern("示例：yyyy-MM-dd")
        dialog.find<TextView>(R.id.tv_date_ymd_).text = mSdf.format(today)

        dialog.find<LinearLayout>(R.id.ll_date_ymd).singleClick {
            dialog.dismiss()
            mSdf.applyPattern("yyyy年M月dd日")
            mSignFragment.addText(mSdf.format(Calendar.getInstance().time))
        }
        dialog.find<LinearLayout>(R.id.ll_date_num).singleClick {
            dialog.dismiss()
            mSdf.applyPattern("yyyyMMdd")
            mSignFragment.addText(mSdf.format(Calendar.getInstance().time))
        }
        dialog.find<LinearLayout>(R.id.ll_date_ymd_s).singleClick {
            dialog.dismiss()
            mSdf.applyPattern("yyyy/MM/dd")
            mSignFragment.addText(mSdf.format(Calendar.getInstance().time))
        }
        dialog.find<LinearLayout>(R.id.ll_date_ymd_).singleClick {
            dialog.dismiss()
            mSdf.applyPattern("yyyy-MM-dd")
            mSignFragment.addText(mSdf.format(Calendar.getInstance().time))
        }
        dialog.bottomShow()
    }

    override fun doOnBackPressed() {
        MsgDialog(
            mContext, "退出提醒", "您还未保存，确定要退出吗？"
        ) {
            if (it == 1) super.doOnBackPressed()
        }.show()
    }
}